codeforces 254A

给2n个数,问能不能组成n对数,使每对数中的两个数值相同。n小于300000,a[i]小于5000。水题。

做法很多,可以排序,可以每输入一个数判断同样数值的数是否输入过,可以用链表储存每个数值出现过的位置。
给出我用链表过的程序。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53

#include<stdio.h>
#include<cstring>
#include<algorithm>
#include<string.h>
#include<iostream>
#include<cmath>
#include<map>
#include<queue>
#include<numeric>
#include<set>
#pragma comment(linker, "/STACK:10240000000,10240000000")
using namespace std;
#define mem(x,y) memset(x,y,sizeof(x))
#define inf 0x3f3f3f3f
#define debug puts("-----")
#define maxn 50000+4
#define uLL unsigned long long
#define LL long long
int next[600000+6];
int b[5000+3];
int pre[5000+3];
int main()
{

freopen("input.txt", "r", stdin);
freopen("output.txt", "w", stdout);
int n;
mem(b,0);
mem(pre,-1);
scanf("%d",&n);
for(int i=0;i<2*n;i++)
{
int t;
scanf("%d",&t);
b[t]++;
next[i]=pre[t];
pre[t]=i;
}
for(int i=0;i<=5000;i++)
if(b[i]%2)
{
puts("-1");
return 0;
}
for(int i=0;i<=5000;i++)
{
for(int j=pre[i],cnt=0;~j;j=next[j],cnt++)
{
printf("%d",j+1);
printf("%c",cnt%2?'\n':' ');
}
}
}

EOF